namespace Plugins.Engine
{
    using System;
    using Plugins.Interfaces;

    [Serializable]
    public sealed class PluginPropertyValue<T> : PluginPropertyValue, IPluginProperty<T>, IPluginConvertible<T>, IEquatable<T>, IPluginProperty
    {
        //private Type _type = typeof(T);
        private IPluginPropertyConverter<T> _converter;
        private T _defaultValue;

        public PluginPropertyValue(PluginPropertyValue property) : base(property)
        {
        }

        public PluginPropertyValue(PluginPropertyValue property, T defaultValue) : base(property)
        {
            this._defaultValue = defaultValue;
        }

        public PluginPropertyValue(PluginPropertyValue property, T defaultValue, IPluginPropertyConverter<T> converter) : base(property)
        {
            this._defaultValue = defaultValue;
            this._converter = converter;
        }

        public Type RuntimeType { get { return typeof(T); } }

        public bool Equals(T other)
        {
            if (this._converter != null)
            {
                return (string.Compare(Value, PluginPropertyConverter.ConvertToString<T>(this._converter, other), StringComparison.Ordinal) == 0);
            }
            return (string.Compare(Value, PluginPropertyConverter.ConvertToString<T>(other), StringComparison.Ordinal) == 0);
        }

        public T GetValue()
        {
            if (this._converter != null)
            {
                return PluginPropertyConverter.ConvertFromString<T>(this._converter, Value);
            }
            return PluginPropertyConverter.ConvertFromString<T>(Value);
        }

        public T GetValue(IPluginPropertyConverter<T> converter)
        {
            if (converter != null)
            {
                return PluginPropertyConverter.ConvertFromString<T>(converter, Value);
            }
            return this.GetValue();
        }

        public void SetValue(T value)
        {
            if (this._converter != null)
            {
                Value = PluginPropertyConverter.ConvertToString<T>(this._converter, value);
            }
        }

        public void SetValue(T value, IPluginPropertyConverter<T> converter)
        {
            if (converter != null)
            {
                this.SetValue(value, converter);
            }
            this.SetValue(value);
        }

        public T DefaultValue
        {
            get
            {
                return this._defaultValue;
            }
        }
    }
}

